home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / std / c++ / 392 < prev    next >
Encoding:
Text File  |  1996-08-06  |  3.8 KB  |  104 lines

  1. Path: chronicle.mti.sgi.com!austern
  2. From: clamage@Eng.Sun.COM (Steve Clamage)
  3. Newsgroups: comp.std.c++
  4. Subject: Re: Correctness of compilers behavior
  5. Date: 20 Feb 1996 13:42:34 PST
  6. Organization: Sun Microsystems Inc.
  7. Approved: austern@isolde.mti.sgi.com
  8. Message-ID: <4gdc37$cqv@engnews1.Eng.Sun.COM>
  9. References: <199602180416.UAA01735@kronstadt.rahul.net>
  10. Reply-To: clamage@Eng.Sun.COM
  11. NNTP-Posting-Host: isolde.mti.sgi.com
  12. X-Original-Date: 20 Feb 1996 20:48:39 GMT
  13. X-Auth: PGPMoose V1.1 PGP comp.std.c++
  14.     iQBVAwUBMSpAYky4NqrwXLNJAQEWQAH/RkJZoKQGhF+SNUkGeSgA5GsjcvE7eemd
  15.     DndF/IF8DUsEzYY/bOY4hnCNw7kf4JAoLDpk5bPMujB4razPHQPP4w==
  16.     =Rh5f
  17. Originator: austern@isolde.mti.sgi.com
  18.  
  19. In article UAA01735@kronstadt.rahul.net, Ian T Zimmerman <itz@rahul.net> writes:
  20. >In article <4g3i93$9lp@mulga.cs.mu.OZ.AU> fjh@munta.cs.mu.OZ.AU
  21. >(Fergus Henderson) writes:
  22. >
  23. >> >  for (unsigned i=0; i<size; ++i) {
  24. >> >    (bptr+i)->~B();
  25. >> >    new(aptr+i) A;
  26. >> >  }
  27. >> >
  28. >
  29. >> >int main(void)
  30. >> >{
  31. >> >  A* arr=foo(2);
  32. >> >  delete [] arr;
  33. >> 
  34. >> This has undefined behaviour.  It contravenes 5.3.5[expr.delete]/2, which
  35. >> says that the expression passed to `delete []' must be a pointer to the
  36. >> first element of an array of objects allocated with `new []'; this is not
  37. >> the case, because although there once was such an array at that memory
  38. >> location, its lifetime ended when the memory was overwritten by the calls
  39. >> to placement new (see 3.8[basic.life]/1).
  40. >
  41. >Is it relevant here that A and B are unrelated classes? 
  42.  
  43. No. It only matters that A and B are not the same type. If A were derived
  44. from B or vice-versa the code would still be wrong. Example:
  45.     class A : public B { ... };
  46.     B* p = new A[10]; // legal, but a bad idea
  47.     delete[] p; // error that does not have to be diagnosed 
  48.  
  49. Such code is valid for single objects, but not for arrays. Although an A
  50. is-a B, an array of A is NOT an array of B. Ordinarily you don't want
  51. C-style arrays of objects, especially polymorphic objects. You probably
  52. want an array of pointers so that you get object instead of value semantics,
  53. or an array class of values to avoid the inconvenient properties of C-style
  54. arrays.
  55.  
  56. >What about the following code?
  57. >
  58. >A a;
  59. >
  60. >A* as = new A [10];
  61. >
  62. >for (int i = 0; i < 10; ++i) {
  63. >    new (&as[i]) A(a);
  64. >}
  65. >delete [] as;
  66.  
  67. It is valid to construct an object on top of the storage previously
  68. used for another object of the same type, so this code is mostly OK.
  69. Notice that you don't destroy the objects that were constructed with
  70. the default constructor.
  71.  
  72. In the general case you would want to destroy the original objects
  73. before building new objects in their storage locations. Related to
  74. this point, the compiler will construct the original objects from
  75. index 0 up to index 9, and will destroy them in the reverse order.
  76. If the objects have any inter-dependencies, you might need to
  77. mimic that behavior to ensure a valid program. So you might write:
  78.  
  79.     A* as = new A[10]; // construct as[0] through as[9] in that order
  80.     for( int i=10; --i>=0; )
  81.         as[i]->~A(); // destroy in reverse order
  82.     for( int i=0; i<10; ++i )
  83.         new (&as[i]) A(a); // contruct from as[0] through as[9]
  84.     ...
  85.     delete[] as; // destroys as[9] down to as[0]
  86.  
  87. If all you want is an array of values, you don't have to go through the
  88. extra construction and destruction if the number of elements is known
  89. at compile time:
  90.     A as[10] = { a, a, a, a, a, a, a, a, a, a };
  91. or perhaps
  92.     A as[10] = { A(arg0), A(arg1), A(arg2), ... , A(arg9) };
  93. to get different values in different slots.
  94.  
  95. ---
  96. Steve Clamage, stephen.clamage@eng.sun.com
  97. ---
  98. [ To submit articles: Try just posting with your newsreader.  If that fails,
  99.                       use mailto:std-c++@ncar.ucar.edu
  100.   FAQ:    http://reality.sgi.com/employees/austern_mti/std-c++/faq.html
  101.   Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html
  102.   Comments? mailto:std-c++-request@ncar.ucar.edu 
  103. ]
  104.